package zhuyouyong.bottomtab

import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Path
import android.os.Handler
import android.os.Looper
import android.util.AttributeSet
import android.util.TypedValue
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat

/**
 * @author zhuyouyong <zhuyouyong@bm-intelligent.com>
 * Created on 2021/7/10.
 */
class CommonTabExt(context: Context, attrs: AttributeSet? = null) : CustomLayout(context, attrs) {
    private lateinit var texts: Array<LabelTextView>
    private var disableClick = false
    private var clickListener: ((Int) -> Unit)? = null
    private val clickTime = resources.getInteger(R.integer.zyy_click_time).toLong()
    private var currentPos = 0
    private val commonColor = ContextCompat.getColor(context, R.color.zyy_common_color)
    private val accentColor = ContextCompat.getColor(context, R.color.zyy_accent_color)
    private val colorStateList = ColorStateList(
        arrayOf(
            intArrayOf(android.R.attr.state_selected),
            intArrayOf(android.R.attr.state_pressed),
            intArrayOf(-android.R.attr.state_selected)
        ),
        intArrayOf(accentColor, accentColor, commonColor)
    )
    private val borderPaint = Paint().apply { color = commonColor }
    private val bgPaint = Paint().apply {
        color = ContextCompat.getColor(context, R.color.zyy_bg_color)
    }
    private val workHandler = Handler(Looper.getMainLooper())
    private val itemHeight = resources.getDimensionPixelSize(R.dimen.zyy_tab_height)
    private var itemWidth = 0
    private val head = resources.getDimensionPixelSize(R.dimen.zyy_head_height)
    private val headPath = Path()
    private val middleDrawablePadding = resources.getDimensionPixelSize(R.dimen.zyy_drawable_padding)
    private var textPadding = 0

    override fun setContent(vararg contents: Pair<String, Int>) {
        setWillNotDraw(false)
        clipChildren = false
        items = Array(contents.size) {
            View(context).apply {
                foreground = ContextCompat.getDrawable(
                    context,
                    context.resourceId(android.R.attr.selectableItemBackground)
                )
                layoutParams = LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT
                )
                addView(this)
            }
        }
        val txtSize = resources.getDimensionPixelSize(R.dimen.zyy_text_size)
        texts = Array(contents.size) {
            LabelTextView(context).apply {
                textSize = txtSize.toFloat()
                setTextColor(colorStateList)
                gravity = Gravity.CENTER_HORIZONTAL
                layoutParams = LayoutParams(
                    ViewGroup.LayoutParams.WRAP_CONTENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT
                )
                addView(this)
            }
        }
        contents.forEachIndexed { index, pair ->
            items[index].setOnClickListener { onClick(index) }
            texts[index].apply {
                text = pair.first
                setCompoundDrawablesWithIntrinsicBounds(0, pair.second!!, 0, 0)
                /*TextViewCompat.setCompoundDrawableTintList(this, colorStateList)*/
                if (index == 2) compoundDrawablePadding = middleDrawablePadding
            }
        }
        texts[0].isSelected = true
    }
    
    fun setLabel(
        index: Int, drawableId: Int,
        paddingStart: Float = 8.dp.toFloat(), paddingTop: Float = 6.dp.toFloat()
    ) {
        texts[index].setLabel(drawableId, paddingStart, paddingTop)
    }
    
    fun setBorderColor(color: Int) {
        borderPaint.color = color
    }
    
    override fun setClickListener(click: (Int) -> Unit) {
        clickListener = click
    }
    
    private fun onClick(pos: Int) {
        if (disableClick || currentPos == pos) return
        disableClick = true
        texts[currentPos].isSelected = false
        currentPos = pos
        texts[currentPos].isSelected = true
        workHandler.postDelayed({
            disableClick = false
            clickListener?.invoke(pos)
        }, clickTime)
    }

    override fun getCurrentPos() = currentPos

    private fun Context.resourceId(attr: Int) = TypedValue().let {
        theme.resolveAttribute(attr, it, true)
        it.resourceId
    }
    
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        itemWidth = measuredWidth / items.size
        val itemWidthSpec = itemWidth.toExactlyMeasureSpec()
        texts.forEach { it.autoMeasure() }
        textPadding = (itemHeight - texts[0].measuredHeight)/2
        items.forEachIndexed { index, view ->
            when (index) {
                2 -> view.measure(itemWidthSpec, (itemHeight + head).toExactlyMeasureSpec())
                else -> view.measure(itemWidthSpec, itemHeight.toExactlyMeasureSpec())
            }
        }
        setMeasuredDimension(measuredWidth, itemHeight + head)
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        items.forEachIndexed { index, view ->
            val previous = index - 1
            val x = if (previous >= 0) items[previous].right else 0
            val y = if (index == 2) 0 else head
            view.layout(x, y)
            when (index) {
                0 -> texts[0].layout((itemWidth - texts[0].measuredWidth)/2, head + textPadding)
                else -> {
                    val left = items[index].left + (itemWidth - texts[index].measuredWidth)/2
                    texts[index].layout(
                        left,
                        texts[0].bottom - texts[index].measuredHeight,
                        left + texts[index].measuredWidth,
                        texts[0].bottom
                    )
                }
            }
        }
        makeHeadPath()
    }

    private fun makeHeadPath() = headPath.run {
        reset()
        val step = itemWidth/16f
        moveTo(items[2].left + step*3, head.toFloat())
        quadTo(
            items[2].left + step*8, -head.toFloat(),
            items[2].right - step*3, head.toFloat()
        )
        close()
    }
    
    override fun onDraw(canvas: Canvas) {
        canvas.run {
            drawRect(0f, head.toFloat(), width.toFloat(), height.toFloat(), bgPaint)
            drawPath(headPath, bgPaint)
        }
    }
    
    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        workHandler.removeCallbacksAndMessages(null)
    }
}